package com.fj.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fj.condition.UserRegisterCondition;
import com.fj.entity.User;
import com.fj.enums.UserActivatedEnum;
import com.fj.enums.UserDeletedEnum;
import com.fj.enums.UserRegistryTypeEnum;
import com.fj.handler.BusinessException;
import com.fj.mapper.UserMapper;
import com.fj.response.ResultCode;
import com.fj.service.EmailService;
import com.fj.service.SendSmsService;
import com.fj.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService{

    @Autowired
    private EmailService emailService;

    @Autowired
    private SendSmsService sendSmsService;

    @Resource
    private RedisTemplate<String,Object> redisTemplate;



    @Override
    public boolean checkUser(String name) {
        LambdaQueryWrapper<User> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(User::getUserCode,name);
        User selectOne = this.baseMapper.selectOne(wrapper);
        if(selectOne!=null){
            throw new BusinessException(ResultCode.USER_ACCOUNT_ALREADY_EXIST.getCode(),
                    ResultCode.USER_ACCOUNT_ALREADY_EXIST.getMessage());
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean userRegistry(UserRegisterCondition userRegisterCondition, String registryType) {
        //判断用户是否存在
        String userCode=userRegisterCondition.getUserCode();
        LambdaQueryWrapper<User> wrapper=new LambdaQueryWrapper();
        wrapper.eq(User::getUserCode,userCode);
        User ckuser = this.baseMapper.selectOne(wrapper);
        if(ckuser!=null){
            throw new BusinessException(ResultCode.USER_ACCOUNT_ALREADY_EXIST.getCode(),
                    userCode+"用户已存在");
        }
        //不存在，将信息存入数据库中
        User user=new User();
        user.setUserName(userRegisterCondition.getUserName());
        user.setUserCode(userRegisterCondition.getUserCode());

        //加密处理
        userRegisterCondition.setUserPassword(SecureUtil.md5(userRegisterCondition.getUserPassword()));
        BeanUtils.copyProperties(userRegisterCondition,user);

        user.setUserType(UserRegistryTypeEnum.BY_SELF.getTypeCode());
        user.setActivated(UserActivatedEnum.NOT_ACTIVATED.getActivated());
        user.setIsDeleted(UserDeletedEnum.NOT_DELETE.getDeletedCode());

        this.baseMapper.insert(user);
        String code= RandomUtil.randomNumbers(6);
        switch (registryType){
            case "email":
                //邮箱
                emailService.sendStringEmail(userRegisterCondition.getUserCode(),"爱旅行邮箱激活码","您的激活码是："+code);
                break;
            case "phone":
                //短信
                sendSmsService.sendSms(userRegisterCondition.getUserCode(),code);
                break;
        }
        //将激活码存入Redis,并设置过期时间
        redisTemplate.opsForValue().set(userRegisterCondition.getUserCode(),code,300, TimeUnit.SECONDS);
        return true;
    }

    @Override
    public boolean activatedUser(String userCode, String code) {
        //查询数据库，判断账户是否存在，并判断账户是否激活
        LambdaQueryWrapper<User> wrapper=new LambdaQueryWrapper<>();

        wrapper.eq(User::getUserCode,userCode);
        User user = this.baseMapper.selectOne(wrapper);
        if(user==null){
            //账户不存在则抛出
            throw new BusinessException(ResultCode.USER_ACCOUNT_NOT_EXIST.getCode(),
                    ResultCode.USER_ACCOUNT_NOT_EXIST.getMessage());
        }else{
            //账户已激活则抛出
            if(user.getActivated()==1){
                throw new BusinessException(ResultCode.COMMON_FAIL.getCode(),
                        userCode+"账户已激活");
            }
        }
        //判断Redis中是否存在
        if(!redisTemplate.hasKey(userCode)){
            throw new BusinessException(ResultCode.USER_REGISTRY_CODE_EXPIRED.getCode(),
                    ResultCode.USER_REGISTRY_CODE_EXPIRED.getMessage());
        }
        //获取redis中的code并判断是否一致,并修改激活状态
        Object redisCode=redisTemplate.opsForValue().get(userCode);
        int updateById=0;
        if(code.equals(redisCode)){
            //一致，修改账户激活
            user.setActivated(UserActivatedEnum.ACTIVATED.getActivated());
            updateById = this.baseMapper.updateById(user);
        }else{
            //不一致，抛出激活码错误
            throw new BusinessException(ResultCode.USER_REGISTRY_CODE_ERROR.getCode(),
                    ResultCode.USER_REGISTRY_CODE_ERROR.getMessage());
        }
        return updateById>0?true:false;
    }

    @Override
    public void deleteHomeNewsData() {
        this.baseMapper.deleteHomeNewsData();
    }
}
